package icraf.carbon.gui.chart;

import icraf.carbon.gui.ListToolBar;
import icraf.carbon.gui.MenuFactory.MenuProperty;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Random;

import javax.swing.DefaultListModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class BarSettingPanel extends JPanel {
	class ColorListRenderer extends JLabel implements ListCellRenderer {
		private static final long serialVersionUID = 419824652263130225L;
		Color cBack = this.getBackground();
		ArrayList<Color> cList = new ArrayList<Color>();
		Color cSelect = Color.white;

		public ColorListRenderer() {
			this.setPreferredSize(new Dimension(60, 20));
		}

		@SuppressWarnings("unchecked")
		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus) {
			cList = (ArrayList<Color>) value;

			if (isSelected) {
				cBack = list.getSelectionBackground();
			} else {
				cBack = list.getBackground();
			}
			this.repaint();
			return this;
		}

		public void paint(Graphics g) {
			if (cList == null)
				return;
			Graphics2D g2 = (Graphics2D) g;
			Dimension dim = getSize();
			int h = (int) dim.getHeight();
			int w = (int) dim.getWidth();
			g2.setColor(cBack);
			g2.fillRect(0, 0, w, h);
			int x = 0;
			int y = 2;
			int wr = w / cList.size();
			for (Color c : cList) {
				g2.setColor(c);
				g2.fillRect(x, y, wr, h - 4);
				x += wr;
			}
		}

	}

	public class Listener implements SettingListener, ListSelectionListener,
			ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getSource().equals(colorTemplatesCB)) {
				updateColorList();
			} else if (MenuProperty.LIST_ADD.isAction(e)) {
				addShapeSetting();
			} else if (MenuProperty.LIST_REMOVE.isAction(e)) {
				removeShapeSetting();
			}
		}

		@Override
		public void settingChanged(Object source) {
			selectedSetting = shapeSettingPanel.getSetting(selectedSetting);
			list.repaint();
		}

		@Override
		public void valueChanged(ListSelectionEvent e) {
			if (e.getValueIsAdjusting() == false) {
				int idx = list.getSelectedIndex();
				if (idx == -1) {
					// shapeSettingPanel.setEnabled(false);
				} else {
					selectedSetting = (ShapeFormat) listModel.getElementAt(idx);
					shapeSettingPanel.setSetting(selectedSetting);
					selectedIndex = idx;
				}
			}
		}

	}

	class ShapeListRenderer extends ShapePreviewPanel implements
			ListCellRenderer {
		private static final long serialVersionUID = 419824652263130225L;

		public ShapeListRenderer() {
			setBorderSpace(5);
			this.setPreferredSize(new Dimension(40, 40));
		}

		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus) {
			this.setShapeSetting((ShapeFormat) value);
			if (isSelected) {
				setColorSpace(list.getSelectionBackground());
			} else {
				setColorSpace(Color.white);
			}
			return this;
		}
	}

	private static final long serialVersionUID = -1497150693627726185L;

	//public static Object[] generateColorTemplate(int nTemplate) {
	public static ArrayList<ArrayList<Color>> generateColorTemplate(int nTemplate) {
		//int nTemplate = 50;
		int nColor = 6;
		//Object tempList[] = new Object[nTemplate];
		ArrayList<ArrayList<Color>> cArr = new ArrayList<ArrayList<Color>>();
		Random r = new Random(64);
		for (int i = 1; i < nTemplate+1; i++) {
			ArrayList<Color> cList0 = new ArrayList<Color>();
			for (int j = 0; j < nColor; j++) {
				int blue = 120 * ((i % 3) % 2) + r.nextInt(135);
				int green = 120 * ((i % 5) % 2) + r.nextInt(135);
				int red = 120 * ((i+1)  % 2) + r.nextInt(135);
				Color c = new Color(red, green, blue);
				cList0.add(c);
			}
			cArr.add(cList0);
			//tempList[i-1] = cList0;
		}
		//return tempList;
		return cArr;
	}

	public static void main(String[] args) {
		final JFrame frame = new JFrame();
		BarSettingPanel mainPanel = new BarSettingPanel();

		mainPanel.setPreferredSize(new Dimension(600, 400));
		frame.getContentPane().add(mainPanel, BorderLayout.CENTER);
		frame.pack();
		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				frame.setVisible(true);
			}
		});

	}

	private JComboBox colorTemplatesCB;
	private JList list;
	private Listener listener = new Listener();
	private DefaultListModel listModel;
	private ListToolBar listToolBar;
	private Random random = new Random(3);
	private int selectedIndex = 0;
	private ShapeFormat selectedSetting;
	private ShapeSettingPanel shapeSettingPanel;

	public BarSettingPanel() {
		super(new BorderLayout());

		listModel = new DefaultListModel();

		// Create the list and put it in a scroll pane.
		list = new JList(listModel);
		list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		list.setSelectedIndex(0);
		list.addListSelectionListener(listener);
		list.setVisibleRowCount(5);
		list.setCellRenderer(new ShapeListRenderer());

		JScrollPane listScrollPane = new JScrollPane(list);
		listScrollPane
				.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

		listToolBar = new ListToolBar(listener);
		listToolBar.setFloatable(false);
		JPanel cListPanel = new JPanel(new BorderLayout());
		cListPanel.add(listToolBar, BorderLayout.NORTH);
		cListPanel.add(listScrollPane, BorderLayout.CENTER);

		//Object[] colTempl = generateColorTemplate(50);
		ArrayList<ArrayList<Color>> cList = generateColorTemplate(50);
		Object[] colTempl = cList.toArray();
		colorTemplatesCB = new JComboBox(colTempl);
		colorTemplatesCB.setRenderer(new ColorListRenderer());
		colorTemplatesCB.addActionListener(listener);
		colorTemplatesCB
				.setToolTipText(MenuProperty.CHART_SETTING_COLOR_TEMPLATE
						.getLabel());

		shapeSettingPanel = new ShapeSettingPanel(
				ShapeSettingPanel.SHAPE_REC_SETTING);
		shapeSettingPanel.addSettingListener(listener);
		JPanel pSet = new JPanel(new BorderLayout());
		pSet.add(cListPanel, BorderLayout.CENTER);
		pSet.add(colorTemplatesCB, BorderLayout.SOUTH);

		add(pSet, BorderLayout.WEST);
		add(shapeSettingPanel, BorderLayout.CENTER);

		updateColorList();
	}

	public void addShapeSetting() {
		Color c = new Color(random.nextInt(255), random.nextInt(255),
				random.nextInt(255));
		ShapeFormat s = new ShapeFormat();
		s.fillColor = c;
		listModel.addElement(s);
	}

	public Collection<ShapeFormat> getShapeSettingList() {
		ShapeFormat ss[] = new ShapeFormat[listModel.size()];
		listModel.copyInto(ss);
		return Arrays.asList(ss);
	}

	public void removeShapeSetting() {
		listModel.removeElement(selectedSetting);
		if (selectedIndex < listModel.getSize()) {
			list.setSelectedIndex(selectedIndex);
		} else {
			list.setSelectedIndex(listModel.getSize() - 1);
		}
	}

	public void setShapeSettingList(Collection<ShapeFormat> ss) {
		listModel.removeAllElements();
		for (ShapeFormat s : ss) {
			listModel.addElement(s);
		}
		list.setSelectedIndex(0);
	}

	private void updateColorList() {
		listModel.removeAllElements();
		@SuppressWarnings("unchecked")
		ArrayList<Color> arr = (ArrayList<Color>) colorTemplatesCB
				.getSelectedItem();
		for (Color c : arr) {
			ShapeFormat s = new ShapeFormat();
			s.fillColor = c;
			listModel.addElement(s);
		}
		list.setSelectedIndex(0);
	}

}
